using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Web.Services.Description;
using System.Web.Services.Discovery;
using System.Web.Services.Protocols;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using OpenComposite.Base;
using OpenComposite.Base.Collections;
using OpenComposite.EII.Forms;
using OpenComposite.EII.Repository;
using OpenComposite.Mapper;
using OpenComposite.Repository.Properties;
using OpenComposite.Repository.TFS;


namespace OpenComposite.EII.RepositoryUIs
{
	public partial class UCWebService : RepositoryItemUI
	{
		#region Initialization
		public UCWebService(IServiceProvider serviceProvider)
			: base(serviceProvider)
		{
			InitializeComponent();

			init();
		}
		private void init()
		{
			//
			// _folderList
			//
			//_listWebMethods = new UCRepositoryItemList(_serviceProvider);
			//_listWebMethods.Dock = DockStyle.Fill;
			//groupItems.Controls.Add(_listWebMethods);
		}
		#endregion

		#region Public Members

		#region Properties
		public override IRepositoryItem RepositoryItem
		{
			get
			{
				save();
				return _webService;
			}
			set
			{
				if ( value is WebService ) {
					_webService = (WebService)value;
					load();
				}
			}
		}

		public override string TypeText
		{
			get { return Resources.sWebService; }
		}

		public override string TypeDescription
		{
			get { return ""; }
		}
		#endregion

		#endregion

		#region Private Members

		#region Variables
		private WebService _webService = null;
		//private UCRepositoryItemList _listWebMethods = null;
		private System.Web.Services.Description.ServiceDescription _wsdl = null;
		private BindingListEx<WebMethod> _webMethods = null;
		private string _apiFileName = null;
		private string _apiFilePath = null;
		#endregion

		#region Methods
		private void load()
		{
			if ( _webService == null )
				return;

			_webService.Reload();
			_wsdl = null;

			txtName.Text = _webService.Name;
			txtDesc.Text = _webService.Description;
			txtUrl.Text = _webService.Uri;
			txtNamespace.Text = _webService.Namespace;
			txtProjectLocation.Text = _webService.ExtendedProperties.ProjectLocation;

			dgvWebMethods.RowCount = 0;
			_i = 0;
			_webMethods = _webService.GetWebMethods();
			dgvWebMethods.RowCount = _webMethods.Count;
			dgvWebMethods.AutoResizeColumns();

			if ( _webService.Type == WebService.ServiceType.APIService ) {
				btnShowWSDL.Visible = false;
				btnShowWSDL.Enabled = false;
				label3.Text = "File:";

			} else if ( _webService.Type == WebService.ServiceType.WebService ) {
				btnShowWSDL.Visible = true;
				btnShowWSDL.Enabled = true;
				label3.Text = "Url:";
			}
			if ( tabControl1.SelectedTab == tabUsedBy ) {
				usedByHierarchyWebService.RepositoryItem = this.RepositoryItem as RepositoryItemBaseEx;
			}
			//_listWebMethods.SetParentRepositoryItem(ItemType.WebService, _webService.ID);
		}
		private void save()
		{
			if ( _webService == null )
				_webService = new WebService();

			_webService.Reload();

			_webService.Name = txtName.Text;
			_webService.Description = txtDesc.Text;
			_webService.ExtendedProperties.ProjectLocation = txtProjectLocation.Text;
			if ( _webService.Type == WebService.ServiceType.WebService ) {
				if ( Uri.IsWellFormedUriString(txtUrl.Text, UriKind.Absolute) )
					_webService.Uri = txtUrl.Text;
				else {
					MessageBox.Show("The URL is not well-formed.", "WebService URL", MessageBoxButtons.OK, MessageBoxIcon.Error);
					txtUrl.Focus();
					txtUrl.SelectAll();
				}
			}
		}

		private void updateWS()
		{
			using ( new WaitMouse() ) {
				if ( _webService.Type == WebService.ServiceType.WebService ) {
					discoverWS(true);
				} else if ( _webService.Type == WebService.ServiceType.APIService ) {
					browseForAPI(true);
				}
				load();
			}
		}
		private void discoverWS(bool update)
		{
			_i = 0;
			RepositoryService repSvc = this.GetService(typeof(RepositoryService)) as RepositoryService;
			if ( repSvc == null ) throw new NullReferenceException("RepositoryService not available.");

			bool isChanged = false;
			// Specify the URL to discover.
			string serviceUrl = txtUrl.Text;
			string sourceUrl = txtUrl.Text;
			if ( !sourceUrl.ToLower().EndsWith("?wsdl") ) {
				sourceUrl += "?wsdl";
			}
			System.ServiceModel.Description.MetadataExchangeClient mclient;
			System.ServiceModel.Description.MetadataSet mset = null;

			if ( sourceUrl.StartsWith("http") ) {
				//mclient = new System.ServiceModel.Description.MetadataExchangeClient
				//    (new Uri(sourceUrl), System.ServiceModel.Description.MetadataExchangeClientMode.HttpGet);
				mclient = new MetadataExchangeClient("metadataBinding");
				mclient.MaximumResolvedReferences = 100;
				try {
					//mset = mclient.GetMetadata();
					mset = mclient.GetMetadata(new Uri(sourceUrl), System.ServiceModel.Description.MetadataExchangeClientMode.HttpGet);
				} catch ( Exception ex ) {
					string title = update ? "Update WebService!" : "Discover WebService";
					if ( ex.InnerException != null )
						MessageBox.Show(ex.InnerException.Message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
					else
						MessageBox.Show(ex.Message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}
			} else {
				MessageBox.Show("Please enter an address for the web service.", "Discover Web Service", MessageBoxButtons.OK, MessageBoxIcon.Information);
				return;
			}
			_wsdl = null;

			System.ServiceModel.Description.WsdlImporter importer =
				new System.ServiceModel.Description.WsdlImporter(mset);
			if ( importer.WsdlDocuments.Count > 0 ) {
				_wsdl = importer.WsdlDocuments[0];
			}

			// found wsdl document?
			if ( _wsdl != null ) {
				string nameCallbackInterface = null;
				CodeTypeDeclaration codeTypeClient = null;
				CodeTypeDeclaration codeTypeCallbackInterface = null;
				XmlSchemaSet xsdSet = createXmlSchemaSet();

				//add WSDL Document Namespaces to the Schema Builder
				foreach ( XmlSchema xsd in _wsdl.Types.Schemas ) {
					if ( !xsdSet.Contains(xsd.TargetNamespace) )
						xsdSet.Add(xsd);
				}
				foreach ( XmlSchema xsd in importer.XmlSchemas.Schemas() ) {
					if ( !xsdSet.Contains(xsd.TargetNamespace) )
						xsdSet.Add(xsd);
				}
				xsdSet.Compile();
				//_wsdl.Types.Schemas.Clear();
				foreach ( XmlSchema xsd in xsdSet.Schemas() ) {
					_wsdl.Types.Schemas.Add(xsd);
				}
				_wsdl.Types.Schemas.Compile(null, true);

				// generate contact code
				System.CodeDom.CodeCompileUnit codeContract = new System.CodeDom.CodeCompileUnit();
				System.ServiceModel.Description.ServiceContractGenerator generator =
					new System.ServiceModel.Description.ServiceContractGenerator(codeContract);
				generator.Options = ServiceContractGenerationOptions.AsynchronousMethods | ServiceContractGenerationOptions.ClientClass; //System.ServiceModel.Description.ServiceContractGenerationOptions.None;
				generator.NamespaceMappings.Add(_wsdl.TargetNamespace, _wsdl.Name + "Contract");
				generator.NamespaceMappings.Add("*", _wsdl.Name + "Contract");
				generator.NamespaceMappings.Add("", _wsdl.Name + "Contract");
				System.ServiceModel.Description.ContractDescription cdesc =
					importer.ImportContract(_wsdl.PortTypes[0]);
				System.CodeDom.CodeTypeReference typeRef =
					generator.GenerateServiceContractType(cdesc);

				string codestrContract = "";
				using ( StringWriter sw = new StringWriter() ) {
					Microsoft.CSharp.CSharpCodeProvider csProvider = new Microsoft.CSharp.CSharpCodeProvider();
					System.CodeDom.Compiler.CodeGeneratorOptions options = new System.CodeDom.Compiler.CodeGeneratorOptions();
					options.BlankLinesBetweenMembers = true;
					options.BracingStyle = "C";
					options.ElseOnClosing = true;
					options.IndentString = "\t";
					csProvider.GenerateCodeFromCompileUnit(codeContract, sw, options);
					codestrContract = sw.ToString();
				}

				// save metadata
				string strMetaData = "";
				using ( StringWriter sw = new StringWriter() )
				using ( XmlWriter xw = XmlWriter.Create(sw) ) {
					mset.WriteTo(xw);
					xw.Flush();
					strMetaData = sw.ToString();
				}
				if ( update ) {
					isChanged = ( _webService.Uri != txtUrl.Text || _webService.MetaData != strMetaData );
				}
				if ( !update || isChanged ) {
					#region isChanged
					// set webservice values
					_webService.Name = string.IsNullOrEmpty(_wsdl.Name) ? _wsdl.Services[0].Name : _wsdl.Name;
					_webService.Uri = txtUrl.Text;
					_webService.Namespace = _wsdl.TargetNamespace;
					_webService.Description = string.IsNullOrEmpty(_wsdl.Documentation) ? _wsdl.Services[0].Documentation : _wsdl.Documentation;
					_webService.ContractCSharpCode = codestrContract;
					_webService.MetaData = strMetaData;
					_webService.InterfaceFullName = typeRef.BaseType;

					#region find generated client fullname
					foreach ( CodeNamespace codeNS in codeContract.Namespaces ) {
						foreach ( CodeTypeDeclaration codeType in codeNS.Types ) {
							if ( codeType.IsInterface ) {
								if ( nameCallbackInterface == null ) {
									foreach ( CodeAttributeDeclaration codeattrib in codeType.CustomAttributes ) {
										if ( codeattrib.AttributeType.BaseType.EndsWith(".ServiceContractAttribute") ) {
											foreach ( CodeAttributeArgument attribarg in codeattrib.Arguments ) {
												if ( attribarg.Name == "CallbackContract" ) {
													nameCallbackInterface = ( (CodeTypeOfExpression)attribarg.Value ).Type.BaseType;
													string[] split = nameCallbackInterface.Split('.');
													nameCallbackInterface = split[split.Length - 1];
												}
											}
										}
									}
								} else if ( codeType.Name == nameCallbackInterface ) {
									codeTypeCallbackInterface = codeType;
								}
							}
							foreach ( CodeTypeReference codeTypeRef in codeType.BaseTypes ) {
								if ( codeTypeRef.BaseType.Contains("ClientBase") ) {
									_webService.ClientFullName = codeNS.Name + "." + codeType.Name;
									codeTypeClient = codeType;
								}
							}
						}
					}
					#endregion

					using ( StringWriter sw = new StringWriter() ) {
						_wsdl.Write(sw);
						XmlDocument xd = new XmlDocument();
						xd.LoadXml(sw.ToString());
						_webService.WSDL = xd;
					}

					// update webmethods (operations)
					BindingListEx<WebMethod> lstWMethods = _webService.GetWebMethods();
					BindingListEx<WebMethod> lstWMFounded = new BindingListEx<WebMethod>();
					foreach ( PortType porttype in _wsdl.PortTypes ) {
						foreach ( System.Web.Services.Description.Operation op in porttype.Operations ) {
							bool bIsCallbackMethod = false;
							Repository.WebMethod meth = findWebMethod(lstWMethods, op);
							if ( meth != null ) {
								lstWMFounded.Add(meth);
							} else {
								bool bSC;
								meth = repSvc.GetItem(
									OpenComposite.EII.Repository.ItemType.WebMethod, true, Global.Status.CurrentRepositoryId, false, false, out bSC)
									as Repository.WebMethod;
								Global.Data.AddRepositoryHierarchy(_webService, meth, Global.Status.CurrentRepositoryId);
							}
							meth.BeginEdit();
							meth.Name = op.Name;
							meth.Description = op.Documentation;
							meth.PortType = op.PortType.Name;
							meth.WebServiceID = _webService.ID;
							meth.Action = findAction(op);

							System.ServiceModel.Description.OperationDescription wsop = cdesc.Operations.Find(meth.Name);
							System.ServiceModel.Description.MessageDescription mdIn = null, mdOut = null;
							foreach ( System.ServiceModel.Description.MessageDescription md in wsop.Messages ) {
								if ( md.Direction == System.ServiceModel.Description.MessageDirection.Input )
									mdIn = md;
								else if ( md.Direction == System.ServiceModel.Description.MessageDirection.Output )
									mdOut = md;
							}
							CodeMemberMethod methodClient = findMethodInClass(codeTypeClient, meth.Name, meth.Action);
							if ( methodClient == null && codeTypeCallbackInterface != null ) {
								methodClient = findMethodInClass(codeTypeCallbackInterface, meth.Name, meth.Action);
								if ( methodClient != null ) bIsCallbackMethod = true;
							}
							if ( methodClient != null ) {
								if ( mdIn != null && mdIn.Body != null ) {
									// get input types and names
									string typenames = "", varnames = "";
									foreach ( CodeParameterDeclarationExpression paramDecl in methodClient.Parameters ) {
										if ( typenames != "" ) typenames += ";";
										if ( varnames != "" ) varnames += ";";

										typenames += paramDecl.Type.BaseType;
										if ( paramDecl.Type.ArrayRank > 0 ) {
											typenames += "[";
											for ( int i = 0; i < paramDecl.Type.ArrayRank - 1; i++ ) {
												typenames += ",";
											}
											typenames += "]";
										}
										varnames += paramDecl.Name;
									}
									meth.InputWrapperName = string.Format("{0}:{1}", mdIn.Body.WrapperNamespace, mdIn.Body.WrapperName);
									meth.InputTypeName = typenames;
									meth.InputVariableName = varnames;
								}
								if ( mdOut != null && mdOut.Body != null ) {
									// get output types and names
									meth.OutputWrapperName = string.Format("{0}:{1}", mdOut.Body.WrapperNamespace, mdOut.Body.WrapperName);
									if ( bIsCallbackMethod ) {
										string typenames = "", varnames = "";
										foreach ( CodeParameterDeclarationExpression paramDecl in methodClient.Parameters ) {
											if ( typenames != "" ) typenames += ";";
											if ( varnames != "" ) varnames += ";";

											typenames += paramDecl.Type.BaseType;
											if ( paramDecl.Type.ArrayRank > 0 ) {
												typenames += "[";
												for ( int i = 0; i < paramDecl.Type.ArrayRank - 1; i++ ) {
													typenames += ",";
												}
												typenames += "]";
											}
											varnames += paramDecl.Name;
										}
										meth.OutputTypeName = typenames;
										meth.OutputVariableName = varnames;
									} else {
										meth.OutputTypeName = methodClient.ReturnType.BaseType;
									}
									if ( methodClient.ReturnType.ArrayRank > 0 ) {
										meth.OutputTypeName += "[";
										for ( int i = 0; i < methodClient.ReturnType.ArrayRank - 1; i++ ) {
											meth.OutputTypeName += ",";
										}
										meth.OutputTypeName += "]";
									}
									if ( mdOut.Body.ReturnValue != null || mdOut.Body.Parts.Count > 0 ) {
										meth.OutputVariableName = getOutputVarName(getMessageSchema(op.Messages.Output.Message));// mdOut.Body.ReturnValue.Name;
										if ( !bIsCallbackMethod && !meth.OutputVariableName.Contains(mdOut.Body.ReturnValue.Name) ) {
											meth.OutputVariableName += "/" + mdOut.Body.ReturnValue.Name;
										}
									}
								}
							} else {
								#region Get Input / Output Types and Names by Web Method Message
								System.Reflection.FieldInfo baseType = null;
								if ( mdIn != null && mdIn.Body != null && mdIn.Body.Parts.Count > 0 ) {
									string typenames = "", varnames = "";
									foreach ( MessagePartDescription part in mdIn.Body.Parts ) {
										baseType = part.GetType().GetField("baseType", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
										if ( typenames != "" ) typenames += ";";
										if ( varnames != "" ) varnames += ";";
										object typeobj = baseType.GetValue(part);
										string typenm = null;
										if ( typeobj != null ) {
											typenm = typeobj.ToString();
											foreach ( XmlQualifiedName xqn in xsdSet.GlobalTypes.Names ) {
												if ( xqn.Name == typenm ) {
													typenm = xqn.ToString();
													break;
												}
											}
										}
										if ( typenm != null ) {
											typenames += typenm;
										} else {
											typenames += part.Name;
										}
										varnames += part.Name;
									}
									meth.InputWrapperName = string.Format("{0}:{1}", mdIn.Body.WrapperNamespace, mdIn.Body.WrapperName);
									meth.InputTypeName = typenames;
									meth.InputVariableName = varnames;
								} else {
									meth.InputWrapperName = null;
									meth.InputTypeName = null;
									meth.InputVariableName = null;
								}
								if ( mdOut != null && mdOut.Body != null ) {
									string typenames = "", varnames = "";
									if ( mdOut.Body.Parts.Count > 0 ) {
										foreach ( MessagePartDescription part in mdOut.Body.Parts ) {
											baseType = part.GetType().GetField("baseType", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
											if ( typenames != "" ) typenames += ";";
											if ( varnames != "" ) varnames += ";";
											object typeobj = baseType.GetValue(part);
											string typenm = null;
											if ( typeobj != null ) {
												typenm = typeobj.ToString();
												foreach ( XmlQualifiedName xqn in xsdSet.GlobalTypes.Names ) {
													if ( xqn.Name == typenm ) {
														typenm = xqn.ToString();
														break;
													}
												}
											}
											if ( typenm != null ) {
												typenames += typenm;
											} else {
												typenames += part.Name;
											}
											varnames += part.Name;
										}
									}
									if ( mdOut.Body.ReturnValue != null ) {
										MessagePartDescription part = mdOut.Body.ReturnValue;
										baseType = part.GetType().GetField("baseType", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
										if ( typenames != "" ) typenames += ";";
										if ( varnames != "" ) varnames += ";";
										object typeobj = baseType.GetValue(part);
										string typenm = null;
										if ( typeobj != null ) {
											typenm = typeobj.ToString();
											foreach ( XmlQualifiedName xqn in xsdSet.GlobalTypes.Names ) {
												if ( xqn.Name == typenm ) {
													typenm = xqn.ToString();
													break;
												}
											}
										}
										if ( typenm != null )
											typenames += typenm.ToString();
										else
											typenames += part.Name;
										varnames += part.Name;
									}
									meth.OutputWrapperName = string.Format("{0}:{1}", mdOut.Body.WrapperNamespace, mdOut.Body.WrapperName);
									meth.OutputTypeName = typenames;
									meth.OutputVariableName = varnames;
								} else {
									meth.OutputWrapperName = null;
									meth.OutputTypeName = null;
									meth.OutputVariableName = null;
								}
								#endregion
							}
							meth.EndEdit(true);
							if ( op.Messages.Input != null ) {
								meth.InputSchema = getMessageSchema(op.Messages.Input.Message);//getSchemaFromMessage(op.Messages.Input.Message);
								meth.InputAction = op.Messages.Input.Message.ToString();
							} else {
								meth.InputSchema = null;
								meth.InputAction = null;
							}
							if ( op.Messages.Output != null ) {
								meth.OutputSchema = getMessageSchema(op.Messages.Output.Message);//getSchemaFromMessage(op.Messages.Output.Message);
								meth.OutputAction = op.Messages.Output.Message.ToString();
							} else {
								meth.OutputSchema = null;
								meth.OutputAction = null;
							}

						}
					}
					foreach ( WebMethod wm in lstWMethods ) {
						if ( !lstWMFounded.Contains(wm) ) {
							wm.Delete(false);
						}
					}
					#endregion
				}
			}
			_webService.Save();
			if ( update ) {
				string msg;
				if ( isChanged ) {
					msg = "WebService has been updated with new WSDL.";
				} else {
					msg = "WebService did not changed.";
				}
				MessageBox.Show(msg, "Update WebService!", MessageBoxButtons.OK, MessageBoxIcon.Information);
			}
		}

		private string getOutputVarName(XmlSchema xmlSchema)
		{
			string outputVarName = "";
			bool finished = false;
			XmlSchemaElement xse = null;

			do {
				if ( xse == null ) {
					foreach ( XmlSchemaObject xso in xmlSchema.Items ) {
						xse = xso as XmlSchemaElement;
						if ( xse != null ) break;
					}
					if ( xse == null ) break;
				} else {
					if ( outputVarName != "" ) outputVarName += "/";
					outputVarName += xse.Name;
					if ( xse.SchemaType != null ) {
						XmlSchemaComplexType xsct = xse.SchemaType as XmlSchemaComplexType;
						if ( xsct != null ) {
							XmlSchemaGroupBase xsgb = xsct.Particle as XmlSchemaGroupBase;
							if ( xsgb != null && xsgb.Items.Count == 1 && xsgb.Items[0] is XmlSchemaElement ) {
								xse = (XmlSchemaElement)xsgb.Items[0];
							} else {
								finished = true;
							}
						} else {
							finished = true;
						}
					} else {
						finished = true;
					}
				}
			} while ( !finished );

			return outputVarName;
		}
		private void browseForAPI(bool update)
		{
			RepositoryService repSvc = this.GetService(typeof(RepositoryService)) as RepositoryService;
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			//System.ServiceModel.Description.MetadataExchangeClient mclient;
			//System.ServiceModel.Description.MetadataSet mset = null;

			if ( !update ) {
				OpenFileDialog openDlg = new OpenFileDialog();

				openDlg.AddExtension = true;
				openDlg.CheckFileExists = true;
				openDlg.CheckPathExists = true;
				openDlg.DefaultExt = "dll";
				openDlg.Filter = "Dynamic Link Library (*.dll)|*.dll";
				openDlg.Multiselect = false;
				openDlg.Title = "Browse for API Service file";

				if ( openDlg.ShowDialog() == DialogResult.OK ) {
					_apiFilePath = openDlg.FileName;
					_apiFileName = Path.GetFileName(openDlg.FileName);
					txtUrl.Text = openDlg.FileName;
				}
			}

			_wsdl = null;

			// generate contract code
			_apiFilePath = Path.Combine(Path.Combine(Path.GetTempPath(), "OpenComposite"), txtUrl.Text);
			Assembly apiAssembly = Assembly.LoadFile(_apiFilePath);
			string codestrContract = createAssemblyImage(apiAssembly);

			codestrContract =
				codestrContract.Substring(0, codestrContract.LastIndexOf("|"));

			List<MethodInfo> methods = new List<MethodInfo>();

			using ( FormSelectAPIMethods frmApiMeth = new FormSelectAPIMethods(apiAssembly) ) {
				if ( frmApiMeth.ShowDialog(this) == DialogResult.OK ) {
					methods = frmApiMeth.SelectedMethods;

					// save metadata
					string strMetaData = "";

					// set webservice values
					_webService.Name = apiAssembly.GetName().Name;
					_webService.Uri = _apiFileName;
					_webService.Namespace = apiAssembly.GetName().Name;
					_webService.Description = apiAssembly.GetName().FullName.Replace(",", Environment.NewLine);
					_webService.ContractCSharpCode = codestrContract;
					_webService.MetaData = strMetaData;
					//	ws.InterfaceFullName = typeRef.BaseType;

					_webService.ClientFullName = apiAssembly.GetName().FullName;

					// get webmethods (operations)
					dgvWebMethods.DataSource = null;
					_webMethods.Clear();

					BindingListEx<WebMethod> lstWMethods = _webService.GetWebMethods();
					BindingListEx<WebMethod> lstWMFounded = new BindingListEx<WebMethod>();

					foreach ( MethodInfo method in methods ) {
						string inputschema = null;
						string outputschema = null;
						string inputwrapper = "";
						string inputvars = "";
						string inputtypes = "";
						string outputwrapper = "";
						string outputvars = "";
						string outputtypes = "";

						int inCount = 0;
						int outCount = 0;


						Repository.WebMethod meth = findWebMethod(lstWMethods, method.ToString());

						if ( meth != null ) {
							lstWMFounded.Add(meth);
						} else {
							bool bSC;
							meth = repSvc.GetItem(
								OpenComposite.EII.Repository.ItemType.WebMethod, true, Global.Status.CurrentRepositoryId, false, false, out bSC)
								as Repository.WebMethod;
							Global.Data.AddRepositoryHierarchy(_webService, meth, Global.Status.CurrentRepositoryId);
						}
						meth.BeginEdit();
						meth.Action = method.ToString();
						inputwrapper = method.Name + "Request";
						outputwrapper = method.Name + "Response";

						XmlSchemas xsdsInput = new XmlSchemas();
						XmlSchema xsdInput = new XmlSchema();
						XmlSchemas xsdsOutput = new XmlSchemas();
						XmlSchema xsdOutput = new XmlSchema();
						XmlSchemaExporter xseInput = new XmlSchemaExporter(xsdsInput);
						XmlSchemaExporter xseOutput = new XmlSchemaExporter(xsdsOutput);
						SoapReflectionImporter sriInput = new SoapReflectionImporter();
						SoapReflectionImporter sriOutput = new SoapReflectionImporter();
						XmlTypeMapping xtm = null;
						XmlSchema xsd2 = new XmlSchema();

						XmlWriterSettings xws = new XmlWriterSettings();
						xws.OmitXmlDeclaration = true;

						foreach ( ParameterInfo param in method.GetParameters() ) {
							if ( param.IsOut ) {
								Type t = Type.GetType(param.ParameterType.FullName.Replace("&", ""));
								if ( t != null )
									xtm = sriOutput.ImportTypeMapping(t);
								else
									throw new ArgumentException(string.Format("Unknown reference type {0} cannot be serialized.", param.ParameterType.FullName), param.Name);

								xseOutput.ExportTypeMapping(xtm);
								outCount++;
								outputvars += param.Name + ",";
								outputtypes += param.ParameterType.FullName.Replace("&", "") + ",";
							} else {
								xtm = sriInput.ImportTypeMapping(param.ParameterType);
								inputvars += param.Name + ",";
								inputtypes += param.ParameterType.FullName + ",";
								xseInput.ExportTypeMapping(xtm);
							}
							inCount++;
						}
						XmlSchemaElement xseWrapper = new XmlSchemaElement();
						xseWrapper.Name = inputwrapper;
						XmlSchemaComplexType xsdComplexType = new XmlSchemaComplexType();
						xseWrapper.SchemaType = xsdComplexType;
						XmlSchemaSequence xsdSeq = new XmlSchemaSequence();
						xsdComplexType.Particle = xsdSeq;

						meth.Name = method.Name;
						//meth.Description = op.Documentation;
						//meth.PortType = op.PortType.Name;
						meth.WebServiceID = _webService.ID;
						//meth.Action = findAction(op);

						#region Input
						if ( inCount > 0 ) {
							inputvars = inputvars.Substring(0, inputvars.LastIndexOf(','));
							inputtypes = inputtypes.Substring(0, inputtypes.LastIndexOf(','));

							if ( inCount >= 1 ) {
								foreach ( XmlSchema xsd in xsdsInput )
									foreach ( XmlSchemaObject xso in xsd.Items )
										if ( xso is XmlSchemaElement )
											xsdSeq.Items.Add(xso);
										else if ( xsd2.Items.Contains(xso) == false )
											xsd2.Items.Add(xso);

								xsd2.Items.Add(xseWrapper);
							}

							xsdInput = xsd2;

							using ( MemoryStream ms = new MemoryStream() )
							using ( XmlWriter xw = XmlWriter.Create(ms, xws) ) {
								xsd2.Write(xw);
								xw.Flush();

								ms.Position = 0;
								StreamReader sr = new StreamReader(ms);
								inputschema = sr.ReadToEnd();
							}

							xsdInput.Namespaces.Add("", "http://www.theopencomposite.com/canonical_document");
							xsdInput.TargetNamespace = "http://www.theopencomposite.com/canonical_document";
							//xsdInput.Namespaces.Add("", method.ReflectedType.FullName);
							//xsdInput.TargetNamespace = method.ReflectedType.FullName;
							xsdInput.ElementFormDefault = XmlSchemaForm.Qualified;
							xsdInput.AttributeFormDefault = XmlSchemaForm.Unqualified;

							meth.InputSchema = xsdInput;
							meth.InputTypeName = inputtypes;
							meth.InputVariableName = inputvars;
							meth.InputWrapperName = inputwrapper;

						}

						#endregion

						#region Output
						if ( method.ReturnType != typeof(void) || outCount > 0 ) {
							xsd2 = new XmlSchema();

							xtm = sriOutput.ImportTypeMapping(method.ReturnType);
							xseOutput.ExportTypeMapping(xtm);
							outputvars += "returnValue";
							outputtypes += method.ReturnType.FullName;
							outCount++;

							if ( outCount >= 1 ) {
								xseWrapper = new XmlSchemaElement();
								xseWrapper.Name = outputwrapper;
								xsdComplexType = new XmlSchemaComplexType();
								xseWrapper.SchemaType = xsdComplexType;
								xsdSeq = new XmlSchemaSequence();
								xsdComplexType.Particle = xsdSeq;

								foreach ( XmlSchema xsd in xsdsOutput )
									foreach ( XmlSchemaObject xso in xsd.Items )
										if ( xso is XmlSchemaElement )
											xsdSeq.Items.Add(xso);
										else if ( xsd2.Items.Contains(xso) == false )
											xsd2.Items.Add(xso);

								xsd2.Items.Add(xseWrapper);
							}

							xsdOutput = xsd2;

							using ( MemoryStream ms = new MemoryStream() )
							using ( XmlWriter xw = XmlWriter.Create(ms, xws) ) {
								xsd2.Write(xw);
								xw.Flush();

								ms.Position = 0;
								StreamReader sr = new StreamReader(ms);
								outputschema = sr.ReadToEnd();
							}

							if ( outputvars[outputvars.Length - 1] == ',' )
								outputvars = outputvars.Substring(outputvars.Length - 1, 1);
							if ( outputtypes[outputtypes.Length - 1] == ',' )
								outputtypes = outputtypes.Substring(outputtypes.Length - 1, 1);

							xsdOutput.Namespaces.Add("", "http://www.theopencomposite.com/canonical_document");
							xsdOutput.TargetNamespace = "http://www.theopencomposite.com/canonical_document";
							//xsdInput.Namespaces.Add("", method.ReflectedType.FullName);
							//xsdOutput.TargetNamespace = method.ReflectedType.FullName;
							xsdOutput.ElementFormDefault = XmlSchemaForm.Qualified;
							xsdOutput.AttributeFormDefault = XmlSchemaForm.Unqualified;

							meth.OutputSchema = xsdOutput;
							meth.OutputTypeName = outputtypes;
							meth.OutputVariableName = outputvars;
							meth.OutputWrapperName = outputwrapper;
						}
						#endregion

						//if (inCount <= 1 && outCount <= 1) {
						//} else if (inCount <= 1 && outCount > 1) { 
						//} else if (inCount > 1 && outCount <= 1) {
						//} else if (inCount > 1 && outCount > 1) {
						//}

						meth.EndEdit(true);
					}
					foreach ( WebMethod wm in lstWMethods ) {
						if ( !lstWMFounded.Contains(wm) ) {
							wm.Delete(false);
						}
					}
				}
			}
		}

		private string createAssemblyImage(Assembly apiAssembly)
		{
			StringBuilder[] assemblyImage = new StringBuilder[apiAssembly.GetFiles().Length];
			int i = 0;
			foreach ( FileStream fs in apiAssembly.GetFiles(true) ) {
				byte[] bytes = new byte[fs.Length];
				fs.Read(bytes, 0, (int)fs.Length);
				assemblyImage[i] = new StringBuilder();
				foreach ( byte data in bytes ) {
					assemblyImage[i].Append(data.ToString()).Append(",");
				}
				i++;
			}

			string codestrContract = null;
			foreach ( StringBuilder image in assemblyImage ) {
				codestrContract += image.ToString().Substring(0, image.ToString().LastIndexOf(',')) + "|";
			}

			return codestrContract;
		}

		private string findAction(System.Web.Services.Description.Operation op)
		{
			string action = "";
			foreach ( System.Web.Services.Description.Binding binding in _wsdl.Bindings ) {
				if ( binding.Type.Name == op.PortType.Name ) {
					foreach ( OperationBinding opBinding in binding.Operations ) {
						if ( opBinding.Name == op.Name ) {
							foreach ( object extObj in opBinding.Extensions ) {
								SoapOperationBinding soapBind = extObj as SoapOperationBinding;
								Soap12OperationBinding soap12Bind = extObj as Soap12OperationBinding;
								if ( soapBind != null ) {
									action = soapBind.SoapAction;
									goto End;
								} else if ( soap12Bind != null ) {
									action = soap12Bind.SoapAction;
									goto End;
								}
							}
						}
					}
				}
			}
End:
			return action;
		}
		private CodeMemberMethod findMethodInClass(CodeTypeDeclaration codeClass, string methodName, string actionName)
		{
			CodeMemberMethod resultMethod = null;
			foreach ( CodeTypeMember codeMember in codeClass.Members ) {
				CodeMemberMethod method = codeMember as CodeMemberMethod;
				if ( method == null ) continue;

				string action = "";
				foreach ( CodeAttributeDeclaration attrib in method.CustomAttributes ) {
					if ( attrib.AttributeType.BaseType == typeof(OperationContractAttribute).FullName ) {
						foreach ( CodeAttributeArgument arg in attrib.Arguments ) {
							CodePrimitiveExpression primExpr = arg.Value as CodePrimitiveExpression;
							if ( arg.Name == "Action" && primExpr != null && primExpr.Value != null ) {
								action = primExpr.Value.ToString();
								break;
							}
						}
						if ( action != "" ) break;
					} else if ( attrib.AttributeType.BaseType == typeof(SoapDocumentMethodAttribute).FullName ) {
						foreach ( CodeAttributeArgument arg in attrib.Arguments ) {
							CodePrimitiveExpression primExpr = arg.Value as CodePrimitiveExpression;
							if ( arg.Name == "" && primExpr != null && primExpr.Value != null ) {
								action = primExpr.Value.ToString();
								break;
							}
						}
						if ( action != "" ) break;
					}
				}
				if ( !actionName.Contains("/") ) {
					actionName = "/" + actionName;
				}
				if ( ( string.IsNullOrEmpty(action) && method.Name == methodName ) ||
					 ( action.EndsWith(actionName) && method.Name == methodName ) ) {
					resultMethod = method;
				}
			}
			return resultMethod;
		}
		//private CodeMemberMethod findMethodInClass(CodeTypeDeclaration codeClass, string methodName, string returnTypeName)
		//{
		//    CodeMemberMethod resultMethod = null;
		//    foreach ( CodeTypeMember codeMember in codeClass.Members ) {
		//        CodeMemberMethod method = codeMember as CodeMemberMethod;
		//        if ( method == null ) continue;

		//        if ( method.Name == methodName &&
		//             ( ( string.IsNullOrEmpty(returnTypeName) && method.PrivateImplementationType == null ) ||
		//               ( !string.IsNullOrEmpty(returnTypeName) && method.ReturnType.BaseType.EndsWith("." + returnTypeName) ) ) ) {
		//            resultMethod = method;
		//            break;
		//        } else {
		//            string action = "";
		//            foreach ( CodeAttributeDeclaration attrib in method.CustomAttributes ) {
		//                if ( attrib.AttributeType.BaseType == typeof(OperationContractAttribute).FullName ) {
		//                    foreach ( CodeAttributeArgument arg in attrib.Arguments ) {
		//                        CodePrimitiveExpression primExpr = arg.Value as CodePrimitiveExpression;
		//                        if ( arg.Name == "Action" && primExpr != null && primExpr.Value != null ) {
		//                            action = primExpr.Value.ToString();
		//                            break;
		//                        }
		//                    }
		//                    if ( action != "" ) break;
		//                } else if ( attrib.AttributeType.BaseType == typeof(SoapDocumentMethodAttribute).FullName ) {
		//                    foreach ( CodeAttributeArgument arg in attrib.Arguments ) {
		//                        CodePrimitiveExpression primExpr = arg.Value as CodePrimitiveExpression;
		//                        if ( arg.Name == "" && primExpr != null && primExpr.Value != null ) {
		//                            action = primExpr.Value.ToString();
		//                            break;
		//                        }
		//                    }
		//                    if ( action != "" ) break;
		//                }
		//            }
		//            if ( action.EndsWith("/" + methodName) &&
		//                 ( ( string.IsNullOrEmpty(returnTypeName) && method.PrivateImplementationType == null ) ||
		//                   ( !string.IsNullOrEmpty(returnTypeName) && method.ReturnType.BaseType.EndsWith("." + returnTypeName) ) ) ) {
		//                resultMethod = method;
		//            }
		//        }
		//    }
		//    return resultMethod;
		//}

		private static Repository.WebMethod findWebMethod(BindingListEx<WebMethod> lstWMethods, System.Web.Services.Description.Operation op)
		{
			Repository.WebMethod meth = lstWMethods.Find(delegate(WebMethod wm)
												{
													return ( wm.Name == op.Name );
												});
			return meth;
		}

		private static Repository.WebMethod findWebMethod(BindingListEx<WebMethod> lstWMethods, string name)
		{
			Repository.WebMethod meth = lstWMethods.Find(delegate(WebMethod wm)
												{
													return ( wm.Action == name );
												});
			return meth;
		}

		private int _i = 0;
		private XmlSchema getMessageSchema(XmlQualifiedName msgname)
		{
			//get Message from WSDL Document
			System.Web.Services.Description.Message msg = _wsdl.Messages[msgname.Name];

			//create new Schema Builder for assembling the Message Schema
			XmlSchema xsdResult = new XmlSchema();
			xsdResult.ElementFormDefault = XmlSchemaForm.Qualified;

			List<string> lstAddedNS = new List<string>();
			//add WSDL Document Namespaces to the Schema Builder
			foreach ( XmlSchema xsd in _wsdl.Types.Schemas ) {
				if ( !string.IsNullOrEmpty(xsd.TargetNamespace) && !lstAddedNS.Contains(xsd.TargetNamespace) ) {
					xsdResult.Namespaces.Add(string.Format("q{0}", _i), xsd.TargetNamespace);
					lstAddedNS.Add(xsd.TargetNamespace);
					_i++;
				} else {
				}
			}

			foreach ( MessagePart messagePart in msg.Parts ) {
				XmlSchemaElement xse =
					_wsdl.Types.Schemas.Find(messagePart.Element, typeof(System.Xml.Schema.XmlSchemaElement))
						as XmlSchemaElement;
				if ( xse != null ) {
					xsdResult.TargetNamespace = xse.QualifiedName.Namespace;
					xsdResult.Items.Add(xse);
				}
			}
			return xsdResult;
		}
		//private void showInformations()
		//{
		//    Repository.WebService ws = this.RepositoryItem as Repository.WebService;
		//    if ( ws == null )
		//        throw new Exception("Repository Item is not a webservice.");

		//    this.SuspendLayout();
		//    try {
		//        if ( ws != null ) {
		//            txtName.Text = ws.Name;
		//            txtDesc.Text = ws.Description;
		//            txtXmlns.Text = ws.Namespace;
		//        } else {
		//            txtName.Text = "- Not Available -";
		//            txtDesc.Text = "";
		//            txtXmlns.Text = "";
		//        }
		//        dgvWebMethods.DataSource = null;
		//        dgvWebMethods.DataSource = _webmethods;
		//    } finally {
		//        this.ResumeLayout(true);
		//    }

		//}

		private XmlSchema getSchema(XmlQualifiedName message,
									DiscoveryClientProtocol client,
									System.Web.Services.Description.ServiceDescription wsdl)
		{
			XmlSchemaSet schemaset = new XmlSchemaSet();
			XmlSchema xsd = null;
			XmlSchemaObject xsdObj = null;
			System.Web.Services.Description.Message msg = wsdl.Messages[message.Name];
			MessagePart part = msg.Parts[0];
			// search in wsdl types
			//wsdl.Types.Schemas.Compile(null, true);
			XmlSchemaElement xsdElement = (XmlSchemaElement)wsdl.Types.Schemas.Find(
				part.Element, typeof(XmlSchemaElement));

			if ( xsdElement != null ) {
				xsdObj = xsdElement;
			} else {
				// search imported documents
				foreach ( XmlSchema schema in wsdl.Types.Schemas ) {
					schemaset.Add(schema);
				}
				schemaset.Compile();

				xsdObj = schemaset.GlobalElements[part.Element];
			}
			if ( xsdObj != null ) {
				xsd = new XmlSchema();
				xsd.Items.Add(xsdObj);
				schemaset.Add(xsd);
				schemaset.Compile();
			}

			start(xsd);

			XmlWriterSettings settings = new XmlWriterSettings();
			settings.Indent = false;
			settings.OmitXmlDeclaration = true;
			settings.ConformanceLevel = ConformanceLevel.Auto;
			using ( StringWriter sw = new StringWriter() )
			using ( XmlWriter xw = XmlWriter.Create(sw, settings) ) {
				xsd.Write(xw, new XmlNamespaceManager(schemaset.NameTable));
				xw.Flush();
				string sXSD = sw.ToString();
			}
			return xsd;
		}
		private void start(XmlSchema schema)
		{
			foreach ( XmlSchemaType type in schema.SchemaTypes.Values ) {
				if ( type is XmlSchemaComplexType ) {
					XmlSchemaComplexType ct = type as XmlSchemaComplexType;
					walkTheParticle(ct.ContentTypeParticle);
				}
			}
			foreach ( XmlSchemaElement el in schema.Elements.Values ) {
				walkTheParticle(el);
			}
			foreach ( XmlSchemaAnnotated xsa in schema.Items ) {
				if ( xsa is XmlSchemaGroup ) {
					XmlSchemaGroup xsg = xsa as XmlSchemaGroup;
					walkTheParticle(xsg.Particle);
				}
			}
		}

		private XmlSchema getSchemaFromMessage(XmlQualifiedName msgname)
		{
			//get Message from WSDL Document
			System.Web.Services.Description.Message msg = _wsdl.Messages[msgname.Name];

			//create new Schema Builder for assembling the Message Schema
			XmlSchema xsdResult = new XmlSchema();
			xsdResult.ElementFormDefault = XmlSchemaForm.Qualified;

			List<string> lstAddedNS = new List<string>();
			XmlSchemaSet xsdSet = new XmlSchemaSet();

			//add WSDL Document Namespaces to the Schema Builder
			int i = 0;
			foreach ( XmlSchema xsd in _wsdl.Types.Schemas ) {
				//if ( !xsdSet.Contains(xsd.TargetNamespace) ) {
				//    xsdSet.Add(xsd);
				//    xsdSet.Compile();
				//}
				if ( !lstAddedNS.Contains(xsd.TargetNamespace) ) {
					xsdResult.Namespaces.Add(string.Format("q{0}", i), xsd.TargetNamespace);
					lstAddedNS.Add(xsd.TargetNamespace);
				}
				i++;
			}

			xsdSet.Compile();
			foreach ( XmlSchema xsd in xsdSet.Schemas() ) {
				//if ( !_wsdl.Types.Schemas.Contains(xsd.TargetNamespace) ) {
				//    _wsdl.Types.Schemas.Add(xsd);
				//}
				if ( !lstAddedNS.Contains(xsd.TargetNamespace) ) {
					xsdResult.Namespaces.Add(string.Format("q{0}", i), xsd.TargetNamespace);
					lstAddedNS.Add(xsd.TargetNamespace);
				}
				i++;
			}
			_wsdl.Types.Schemas.Compile(null, true);

			#region process Messages Parts
			foreach ( MessagePart messagePart in msg.Parts ) {
				XmlSchemaElement xse =
					_wsdl.Types.Schemas.Find(messagePart.Element, typeof(System.Xml.Schema.XmlSchemaElement))
						as XmlSchemaElement;
				if ( xse != null ) {
					xsdResult.TargetNamespace = xse.QualifiedName.Namespace;
					xsdResult.Items.Add(xse);
					this.addSchemaElementToSchema(xse, xsdResult, true);
					continue;
				}
				if ( messagePart.Type.IsEmpty == false ) {
					//add Type Definition of the Message Part to the Schema Builder
					this.addSchemaTypeToSchema(messagePart.Type, xsdResult);

					xsdResult.TargetNamespace = messagePart.Type.Namespace;
				}

				if ( messagePart.Element.IsEmpty == false ) {
					//get Element from WSDL
					XmlSchemaObject msgPartObject =
						this.getSchemaObjectFromQName(messagePart.Element, true);

					xsdResult.TargetNamespace = messagePart.Element.Namespace;

					if ( msgPartObject is XmlSchemaElement ) {
						//add Element to the Schema Builder
						this.addSchemaElementToSchema((XmlSchemaElement)msgPartObject, xsdResult, false);
					}

				}

				if ( messagePart.Type.IsEmpty == false ) {
					//create new Element representing the MessagePart Name
					XmlSchemaElement schemaElement = new XmlSchemaElement();
					schemaElement.Name = messagePart.Name;
					schemaElement.SchemaTypeName = messagePart.Type;
					xsdResult.Items.Add(schemaElement);
				}
			}
			#endregion

			//compile Message Schema
			this.checkXmlSchema(xsdResult);

			//return Content of the built Message Schema
			return xsdResult;
		}
		private void processXmlSchemaParticle(XmlSchema xsdResult, XmlSchemaParticle part)
		{
			//<xs: element ... />
			if ( part is XmlSchemaElement ) {
				if ( ( (XmlSchemaElement)part ).SchemaTypeName.IsEmpty == false ) {
					this.addSchemaTypeToSchema(( (XmlSchemaElement)part ).SchemaTypeName, xsdResult);
				}
				if ( ( (XmlSchemaElement)part ).SchemaType is XmlSchemaComplexType ) {
					XmlSchemaComplexType ct = ( (XmlSchemaElement)part ).SchemaType as XmlSchemaComplexType;
					if ( ct.ContentTypeParticle is XmlSchemaSequence ) {
						//get Child Sequence from Complex Type
						XmlSchemaSequence seq = (XmlSchemaSequence)ct.ContentTypeParticle;

						#region process Elements of the Sequence
						foreach ( XmlSchemaParticle partCT in seq.Items ) {
							processXmlSchemaParticle(xsdResult, partCT);
						}
						#endregion
					} else if ( ct.ContentTypeParticle is XmlSchemaChoice ) {
						//get Child Choice from Complex Type
						XmlSchemaChoice choice = (XmlSchemaChoice)ct.ContentTypeParticle;
						foreach ( XmlSchemaParticle partCT in choice.Items ) {
							processXmlSchemaParticle(xsdResult, partCT);
						}
					}
				}

				if ( ( (XmlSchemaElement)part ).RefName.IsEmpty == false ) {
					XmlSchemaElement refElement = (XmlSchemaElement)
						this.getSchemaObjectFromQName(( (XmlSchemaElement)part ).RefName,
						true);
					refElement.Namespaces.Add("", refElement.QualifiedName.Namespace);
					this.addSchemaElementToSchema(refElement, xsdResult, false);
				}
			}

			//<xs:any namespace='a_namespace' />
			if ( part is XmlSchemaAny ) {
				if ( _wsdl.Types.Schemas[( (XmlSchemaAny)part ).Namespace] != null ) {
					XmlSchema anyRefSchema = _wsdl.Types.Schemas[( (XmlSchemaAny)part ).Namespace];

					foreach ( XmlSchemaObject anyObj in anyRefSchema.Items ) {
						xsdResult.Items.Add(anyObj);
					}
					if ( xsdResult.TargetNamespace == null || xsdResult.TargetNamespace == string.Empty ) {
						xsdResult.TargetNamespace = anyRefSchema.TargetNamespace;
					}
				}
			}
		}
		private bool addSchemaTypeToSchema
			(XmlQualifiedName typename, XmlSchema xsdResult)
		{
			XmlSchemaType schemaType = this.getSchemaTypeFromType(typename);
			if ( schemaType == null )
				return false;

			if ( schemaType is XmlSchemaComplexType ) {
				if ( ( (XmlSchemaComplexType)schemaType ).ContentTypeParticle is XmlSchemaSequence ) {
					XmlSchemaSequence seq = (XmlSchemaSequence)
						( (XmlSchemaComplexType)schemaType ).ContentTypeParticle;
					foreach ( XmlSchemaObject item in seq.Items ) {
						if ( item is XmlSchemaElement ) {
							if ( ( (XmlSchemaElement)item ).QualifiedName != typename ) {
								//check if Element already exists in Schema
								bool elementAlreadyAdded = this.checkSchemaObjectExists(
									( (XmlSchemaElement)item ).QualifiedName, xsdResult);
								//process Element
								this.addSchemaElementToSchema((XmlSchemaElement)item,
									xsdResult, true);
							}
						}
						if ( item is XmlSchemaType ) {
							this.addSchemaTypeToSchema(
							  ( (XmlSchemaType)item ).QualifiedName, xsdResult);
						}
					}
				}
			}
			if ( xsdResult.TargetNamespace == null
				| xsdResult.TargetNamespace == string.Empty ) {
				if ( schemaType is XmlSchemaType ) {
					xsdResult.TargetNamespace =
						( (XmlSchemaType)schemaType ).QualifiedName.Namespace;
				}
			}
			if ( xsdResult.Items.Contains(schemaType) == false ) {
				if ( xsdResult.TargetNamespace != schemaType.QualifiedName.Namespace ) {
					XmlQualifiedName qnCurrent = null;
					foreach ( XmlQualifiedName qn in xsdResult.Namespaces.ToArray() ) {
						if ( qn.Namespace == schemaType.QualifiedName.Namespace ) {
							qnCurrent = qn;
							break;
						}
					}
					if ( qnCurrent != null ) {
						schemaType.Namespaces.Add(qnCurrent.Name, schemaType.QualifiedName.Namespace);
					} else {
						string prefix = "q" + xsdResult.Namespaces.Count.ToString();
						xsdResult.Namespaces.Add(prefix, schemaType.QualifiedName.Namespace);
						schemaType.Namespaces.Add(prefix, schemaType.QualifiedName.Namespace);
					}
				}
				xsdResult.Items.Add(schemaType);
			}

			return true;
		}
		/// <summary>
		/// Adds Element that is specified by ElementName to the SchemaBuilder
		/// </summary>
		/// <param name="Element">Xml Element that is to add</param>
		/// <param name="SchemaBuilder"></param>
		/// <param name="ReadOnly">Flag that determines, whether the collected Elements 
		/// Information have to be written into the SchemaBuilder or not. Important for processing
		/// nested Elements</param>
		private void addSchemaElementToSchema
			(XmlSchemaElement element, XmlSchema xsdResult, bool readOnly)
		{

			//process Element's Type
			if ( element.SchemaTypeName.IsEmpty == false ) {
				this.addSchemaTypeToSchema(element.SchemaTypeName, xsdResult);
			}
			//process Element's Reference
			if ( element.RefName.IsEmpty == false ) {
				XmlSchemaElement refElement = (XmlSchemaElement)
					this.getSchemaObjectFromQName(element.RefName, true);
			}


			#region get nested Element Content

			if ( !( element.ElementSchemaType is XmlSchemaComplexType ) ) {
				//process Simple Type
				if ( element.ElementSchemaType is XmlSchemaSimpleType ) {
					if ( !this.addSchemaTypeToSchema(element.SchemaTypeName, xsdResult) &&
						 element.Parent is XmlSchema )
						xsdResult.Items.Add(element);
				}
				return;
			}

			//process Complex Type
			XmlSchemaComplexType complType = (XmlSchemaComplexType)element.ElementSchemaType;

			//assign Complex Type to Element of Interest
			//			schemaElement.SchemaType = complType;

			//if Child is Sequence
			if ( complType.ContentTypeParticle is XmlSchemaSequence ) {
				//get Child Sequence from Complex Type
				XmlSchemaSequence seq = (XmlSchemaSequence)complType.ContentTypeParticle;

				#region process Elements of the Sequence
				foreach ( XmlSchemaParticle part in seq.Items ) {
					processXmlSchemaParticle(xsdResult, part);
				}
				#endregion
			} else if ( complType.ContentTypeParticle is XmlSchemaChoice ) {
				//get Child Choice from Complex Type
				XmlSchemaChoice choice = (XmlSchemaChoice)complType.ContentTypeParticle;
				foreach ( XmlSchemaParticle part in choice.Items ) {
					processXmlSchemaParticle(xsdResult, part);
				}
			}
			#endregion


			if ( readOnly == false ) {
				//add Element to Schema Builder
				if ( xsdResult.Items.Contains(element) == false ) {
					element.Namespaces.Add("tns", element.QualifiedName.Namespace);
					xsdResult.Items.Add(element);
				}
			}
		}
		private XmlSchemaObject getSchemaObjectFromQName
			(XmlQualifiedName QName, bool ObjectIsElement)
		{
			XmlSchema schema = _wsdl.Types.Schemas[QName.Namespace];
			//schema can be null for simple Type Namespaces
			if ( schema == null ) {
				return null;
			}

			foreach ( XmlSchemaObject sObj in schema.Items ) {
				if ( sObj.GetType().GetProperty("QualifiedName") == null ) {
					continue;
				}
				if ( (XmlQualifiedName)( sObj.GetType().GetProperty("QualifiedName")
					.GetValue(sObj, null) ) == QName
					&&
					( ObjectIsElement == true ? ( sObj is XmlSchemaElement ) : !( sObj is XmlSchemaElement ) ) ) {
					return sObj;
				}
			}

			return null;
		}
		private XmlSchemaType getSchemaTypeFromType(XmlQualifiedName typeName)
		{
			return (XmlSchemaType)this.getSchemaObjectFromQName(typeName, false);
		}
		private bool checkSchemaObjectExists(XmlQualifiedName QName, XmlSchema schema)
		{
			foreach ( XmlSchemaObject sObj in schema.Items ) {
				if ( sObj.GetType().GetProperty("QualifiedName") != null ) {
					if ( (XmlQualifiedName)sObj.GetType().GetProperty("QualifiedName")
							.GetValue(sObj, null) == QName ) {
						return true;
					}
				}
			}
			return false;
		}
		private void checkXmlSchema(XmlSchema schema)
		{
			//20050509
			//string schemaContentString = PEPExplorer.GetXmlSchemaContent(XmlSchema);
			//System.IO.MemoryStream memStream = new System.IO.MemoryStream();
			//byte[] schemaContentData =
			//    System.Text.Encoding.ASCII.GetBytes(schemaContentString);
			//memStream.Write(schemaContentData, 0, schemaContentData.Length);
			//memStream.Position = 0;
			//XmlSchema dummySchema = XmlSchema.Read(memStream,
			//    new ValidationEventHandler(XmlValEventHandler));

			XmlSchemaSet xsdset = new XmlSchemaSet();
			xsdset.XmlResolver = null;
			xsdset.Add(schema);
			xsdset.Compile();

			return;
		}

		private void walkTheParticle(XmlSchemaParticle particle)
		{
			if ( particle is XmlSchemaElement ) {
				XmlSchemaElement elem = particle as XmlSchemaElement;

				// todo: insert your processing code here

				if ( elem.RefName.IsEmpty ) {
					XmlSchemaType type = (XmlSchemaType)elem.ElementSchemaType;
					if ( type is XmlSchemaComplexType ) {
						XmlSchemaComplexType ct = type as XmlSchemaComplexType;
						if ( ct.QualifiedName.IsEmpty ) {
							walkTheParticle(ct.ContentTypeParticle);
						} else {
							elem.SchemaType = ct;
							elem.SchemaTypeName = XmlQualifiedName.Empty;
							walkTheParticle(ct.ContentTypeParticle);
						}
					}
				}
			} else if ( particle is XmlSchemaGroupBase ) {
				//xs:all, xs:choice, xs:sequence
				XmlSchemaGroupBase baseParticle = particle as XmlSchemaGroupBase;
				foreach ( XmlSchemaParticle subParticle in baseParticle.Items ) {
					walkTheParticle(subParticle);
				}
			}
		}

		private void showXmlString(string xml)
		{
			XmlDocument xd = new XmlDocument();
			formXmlViewer frm = new formXmlViewer();
			xd.LoadXml(xml);
			frm.XmlDocument = xd;
			frm.ShowDialog();
		}

		//private System.Web.Services.Description.ServiceDescription requestWSDLFromSoapService(Uri uri)
		//{
		//    System.Web.Services.Description.ServiceDescription sdesc = null;

		//    SoapWsdlProxy wp = new SoapWsdlProxy(uri);
		//    WSE2.SoapEnvelope se = wp.RequestDescription();

		//    if ( se != null && se.Body != null && se.Body.FirstChild != null ) {
		//        using ( MemoryStream ms = new MemoryStream() )
		//        using ( XmlWriter xw = XmlWriter.Create(ms) ) {
		//            se.Body.FirstChild.WriteTo(xw);
		//            xw.Flush();
		//            ms.Position = 0;
		//            sdesc = System.Web.Services.Description.ServiceDescription.Read(ms);
		//        }
		//    }
		//    return sdesc;
		//}
		private XmlSchemaSet createXmlSchemaSet()
		{
			XsdDataContractExporter ex = new XsdDataContractExporter();
			ex.Export(typeof(OpenComposite.EII.Designer.Workflow.Help));
			XmlSchemaSet xsdset = ex.Schemas;
			XmlSchema xsdRemove = null;
			foreach ( XmlSchema xsd in xsdset.Schemas() ) {
				if ( xsd.Elements.Contains(new XmlQualifiedName("Help", xsd.TargetNamespace)) ) {
					xsdRemove = xsd;
				}
			}
			xsdset.Remove(xsdRemove);
			return xsdset;
		}

		private void selectLogicalInOut(bool isInput)
		{
			if ( dgvWebMethods.SelectedCells.Count == 0 )
				return;

			int rowIndex = dgvWebMethods.SelectedCells[0].RowIndex;
			WebMethod wmeth = _webMethods[rowIndex];
			FormSelectRepositoryEx frm = new FormSelectRepositoryEx(_webService);
			frm.RepositoryID = Global.Status.CurrentRepositoryId;
			frm.DomainID = Global.Status.CurrentDomainId;
			frm.MultiSelect = false;
			frm.AllowedTypes = new ItemType[] { ItemType.BObject };
			LogicalWebMethod lwm = wmeth.GetLogicalMethod();
			if ( lwm != null ) {
				if ( isInput ) {
					frm.SelectedItem = lwm.InputBusinessObject;
				} else {
					frm.SelectedItem = lwm.OutputBusinessObject;
				}
			}
			if ( frm.ShowDialog() == DialogResult.OK ) {
				if ( lwm == null ) {
					lwm = addLogicalMethodToWebMethod(wmeth, wmeth.Name, _webService.ID);
					dgvWebMethods.UpdateCellValue(colLogicalWMethod.Index, rowIndex);
				}
				if ( frm.SelectedItem is BusinessObject ) {
					if ( isInput ) {
						lwm.InputBusinessObjectID = frm.SelectedItem.ID;
					} else {
						lwm.OutputBusinessObjectID = frm.SelectedItem.ID;
					}
					lwm.Save();
					if ( isInput ) {
						dgvWebMethods.UpdateCellValue(colLogicalInput.Index, rowIndex);
					} else {
						dgvWebMethods.UpdateCellValue(colLogicalOutput.Index, rowIndex);
					}
				}
			}
		}
		private void viewLogicalInOut(bool isInput)
		{
			if ( dgvWebMethods.SelectedCells.Count == 0 )
				return;

			int rowIndex = dgvWebMethods.SelectedCells[0].RowIndex;
			WebMethod wmeth = _webMethods[rowIndex];
			LogicalWebMethod lwm = wmeth.GetLogicalMethod();
			if ( lwm != null ) {
				XmlDocument xd = null;
				if ( isInput && lwm.InputBusinessObjectID > 0 ) {
					xd = new XmlDocument();
					xd.LoadXml(lwm.InputBusinessObject.SchemaString);
				} else if ( !isInput && lwm.OutputBusinessObjectID > 0 ) {
					xd = new XmlDocument();
					xd.LoadXml(lwm.OutputBusinessObject.SchemaString);
				}
				if ( xd != null ) {
					formXmlViewer frm = new formXmlViewer();
					frm.XmlDocument = xd;
					frm.ShowDialog();
				}
			}
		}
		private void removeLogicalInOut(bool isInput)
		{
			if ( dgvWebMethods.SelectedCells.Count == 0 )
				return;

			int rowIndex = dgvWebMethods.SelectedCells[0].RowIndex;
			WebMethod wmeth = _webMethods[rowIndex];
			LogicalWebMethod lwm = wmeth.GetLogicalMethod();
			if ( lwm != null ) {
				if ( isInput ) {
					lwm.InputBusinessObjectID = -1;
				} else {
					lwm.OutputBusinessObjectID = -1;
				}
				lwm.Save();
				if ( isInput ) {
					dgvWebMethods.UpdateCellValue(colLogicalInput.Index, rowIndex);
				} else {
					dgvWebMethods.UpdateCellValue(colLogicalOutput.Index, rowIndex);
				}
			}
		}
		private void viewPhysicalInOut(bool isInput)
		{
			if ( dgvWebMethods.SelectedCells.Count == 0 )
				return;

			int rowIndex = dgvWebMethods.SelectedCells[0].RowIndex;
			WebMethod wmeth = _webMethods[rowIndex];
			XmlDocument xd = null;
			if ( isInput && !string.IsNullOrEmpty(wmeth.InputSchemaString) ) {
				xd = new XmlDocument();
				xd.LoadXml(wmeth.InputSchemaString);
			} else if ( !isInput && !string.IsNullOrEmpty(wmeth.OutputSchemaString) ) {
				xd = new XmlDocument();
				xd.LoadXml(wmeth.OutputSchemaString);
			}
			if ( xd != null ) {
				formXmlViewer frm = new formXmlViewer();
				frm.XmlDocument = xd;
				frm.ShowDialog();
			}
		}
		private void doMapping(bool isInput)
		{
			if ( dgvWebMethods.SelectedCells.Count == 0 )
				return;

			int rowIndex = dgvWebMethods.SelectedCells[0].RowIndex;
			WebMethod wmeth = _webMethods[rowIndex];

			LogicalWebMethod lwm = wmeth.GetLogicalMethod();
			if ( lwm == null )
				return;

			if ( lwm.EndpointRule != null ) {
				LogicalRuleResultEndpoint endpoint = null;
				BindingListEx<LogicalRuleResultEndpoint> endpoints = lwm.GetLogicalRuleResultEndpoints();
				foreach ( LogicalRuleResultEndpoint ep in endpoints ) {
					if ( ep.WebMethod == wmeth || ep.ProxyWebMethod == wmeth ||
						 ep.ProxyCallbackWebMethod == wmeth || ep.CallbackWebMethod == wmeth ) {
						endpoint = ep;
						break;
					}
				}
				string connections, sXslt;
				XmlSchema xsdSource, xsdTarget;
				//XmlSchema xsdIn, xsdOut;
				FormMapping frm = new FormMapping();
				if ( isInput ) {
					if ( lwm.InputBusinessObjectID <= 0 || wmeth.InputSchema == null )
						return;
					sXslt = endpoint.InputXSLT == null ? null : endpoint.InputXSLT.InnerXml;
					connections = endpoint.InputConnections;
					xsdSource = lwm.InputBusinessObject.Schema;
					xsdTarget = wmeth.InputSchema;
				} else {
					if ( lwm.OutputBusinessObjectID <= 0 || wmeth.OutputSchema == null )
						return;
					sXslt = endpoint.OutputXSLT == null ? null : endpoint.OutputXSLT.InnerXml;
					connections = endpoint.OutputConnections;
					xsdSource = wmeth.OutputSchema;
					xsdTarget = lwm.OutputBusinessObject.Schema;
				}
				MetadataSet mset = null;
				System.ServiceModel.Description.WsdlImporter importer = null;
				XmlSchemaSet xsdSet = null;

				if ( _webService.Type == WebService.ServiceType.WebService ) {
					using ( StringReader sr = new StringReader(_webService.MetaData) )
					using ( XmlReader xr = XmlReader.Create(sr) ) {
						mset = MetadataSet.ReadFrom(xr);
					}
					if ( _wsdl == null ) {
						importer = new System.ServiceModel.Description.WsdlImporter(mset);
						if ( importer.WsdlDocuments.Count > 0 ) {
							_wsdl = importer.WsdlDocuments[0];
						}
					}
				} else if ( _webService.Type == WebService.ServiceType.APIService ) {


				}
				// found wsdl document?
				if ( _wsdl != null ) {
					xsdSet = createXmlSchemaSet();

					//add WSDL Document Namespaces to the Schema Builder
					foreach ( XmlSchema xsd in _wsdl.Types.Schemas ) {
						if ( !xsdSet.Contains(xsd.TargetNamespace) )
							xsdSet.Add(xsd);
					}
					if ( importer != null ) {
						foreach ( XmlSchema xsd in importer.XmlSchemas.Schemas() ) {
							if ( !xsdSet.Contains(xsd.TargetNamespace) )
								xsdSet.Add(xsd);
						}
					}
					xsdSet.Compile();
				}
				frm.InitializeMapper(xsdSource, ( isInput ? null : xsdSet ),
									 xsdTarget, ( isInput ? xsdSet : null ),
									 sXslt, connections);
				frm.SetMappingText(lwm, isInput);
				if ( frm.ShowDialog() == DialogResult.OK ) {
					this.Refresh();
					XsltDocument xslt = frm.GetMapping(out connections);
					if ( isInput ) {
						endpoint.InputConnections = connections;
						endpoint.InputXSLT = xslt;
					} else {
						endpoint.OutputConnections = connections;
						endpoint.OutputXSLT = xslt;
					}
					foreach ( LogicalRuleResultEndpoint ep in endpoints ) {
						if ( ep.EndpointRuleResult == endpoint.EndpointRuleResult ) {
							endpoints.Remove(ep);
							break;
						}
					}
					endpoints.Add(endpoint);
					lwm.SetLogicalRuleResultEndpoint(new List<LogicalRuleResultEndpoint>(endpoints));
					lwm.Save();
				}
				//DialogResult result = MessageBox.Show("This Web Method is bound to an Logical Selection Rule Method. To edit the mapping you have to go to the Logical Method Details. Do you want to switch to the Logical Method Details?",
				//    "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
				//if ( result == DialogResult.Yes ) {
				//    Helpers.ShowDetails(lwm, serviceProvider);
				//}
				//return;
			} else {

				string connections, sXslt;
				XmlSchema xsdSource, xsdTarget;
				//XmlSchema xsdIn, xsdOut;
				FormMapping frm = new FormMapping();
				if ( isInput ) {
					if ( lwm.InputBusinessObjectID <= 0 || wmeth.InputSchema == null )
						return;
					sXslt = lwm.InputXSLT == null ? null : lwm.InputXSLT.InnerXml;
					connections = lwm.InputConnections;
					xsdSource = lwm.InputBusinessObject.Schema;
					xsdTarget = wmeth.InputSchema;
				} else {
					if ( lwm.OutputBusinessObjectID <= 0 || wmeth.OutputSchema == null )
						return;
					sXslt = lwm.OutputXSLT == null ? null : lwm.OutputXSLT.InnerXml;
					connections = lwm.OutputConnections;
					xsdSource = wmeth.OutputSchema;
					xsdTarget = lwm.OutputBusinessObject.Schema;
				}
				MetadataSet mset = null;
				System.ServiceModel.Description.WsdlImporter importer = null;
				XmlSchemaSet xsdSet = null;

				if ( _webService.Type == WebService.ServiceType.WebService ) {
					using ( StringReader sr = new StringReader(_webService.MetaData) )
					using ( XmlReader xr = XmlReader.Create(sr) ) {
						mset = MetadataSet.ReadFrom(xr);
					}
					if ( _wsdl == null ) {
						importer = new System.ServiceModel.Description.WsdlImporter(mset);
						if ( importer.WsdlDocuments.Count > 0 ) {
							_wsdl = importer.WsdlDocuments[0];
						}
					}
				} else if ( _webService.Type == WebService.ServiceType.APIService ) {


				}
				// found wsdl document?
				if ( _wsdl != null ) {
					xsdSet = createXmlSchemaSet();

					//add WSDL Document Namespaces to the Schema Builder
					foreach ( XmlSchema xsd in _wsdl.Types.Schemas ) {
						if ( !xsdSet.Contains(xsd.TargetNamespace) )
							xsdSet.Add(xsd);
					}
					if ( importer != null ) {
						foreach ( XmlSchema xsd in importer.XmlSchemas.Schemas() ) {
							if ( !xsdSet.Contains(xsd.TargetNamespace) )
								xsdSet.Add(xsd);
						}
					}
					xsdSet.Compile();
				}
				frm.InitializeMapper(xsdSource, ( isInput ? null : xsdSet ),
									 xsdTarget, ( isInput ? xsdSet : null ),
									 sXslt, connections);
				frm.SetMappingText(lwm, isInput);
				if ( frm.ShowDialog() == DialogResult.OK ) {
					this.Refresh();
					XsltDocument xslt = frm.GetMapping(out connections);
					if ( isInput ) {
						lwm.InputConnections = connections;
						lwm.InputXSLT = xslt;
					} else {
						lwm.OutputConnections = connections;
						lwm.OutputXSLT = xslt;
					}
					lwm.Save();
				}
			}
		}

		private LogicalWebMethod addLogicalMethodToWebMethod(
			WebMethod wmeth, string name, int webserviceId)
		{
			RepositoryService rs = _webService.GetService(typeof(RepositoryService)) as RepositoryService;
			Debug.Assert(rs != null);

			LogicalWebMethod logwm;
			IRepositoryItem parent = null;
			logwm = rs.GetNewItem<LogicalWebMethod>(false, ref parent);
			logwm.Name = name;
			logwm.WebServiceID = webserviceId;
			Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, logwm);
			wmeth.SetLogicalMethod(logwm);
			wmeth.Save();
			return logwm;
		}

		#endregion

		#region Event Handlers

		private void btnShowWSDL_Click(object sender, EventArgs e)
		{
			if ( _webService.WSDL != null ) {
				formXmlViewer frm = new formXmlViewer();
				frm.XmlDocument = _webService.WSDL;
				frm.ShowDialog();
			}
		}

		private void btnUpdate_Click(object sender, EventArgs e)
		{
			updateWS();
		}

		private void dgvWebMethods_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
		{
			if ( e.RowIndex < 0 || e.RowIndex >= _webMethods.Count )
				return;

			WebMethod wmeth = _webMethods[e.RowIndex];

			if ( e.ColumnIndex == colIcon.Index ) {
				// icon
				e.Value = Resources.method;
			} else if ( e.ColumnIndex == colWMName.Index ) {
				// web method name
				e.Value = wmeth.Name;
			} else if ( e.ColumnIndex == colLogicalWMethod.Index ) {
				// logical web method name
				LogicalWebMethod lwm = wmeth.GetLogicalMethod();
				if ( lwm != null ) {
					e.Value = lwm.Name;
				}
			} else if ( e.ColumnIndex == colLogicalInput.Index ) {
				// logical input contract
				LogicalWebMethod lwm = wmeth.GetLogicalMethod();
				if ( lwm != null && lwm.InputBusinessObject != null ) {
					e.Value = lwm.InputBusinessObject.Name;
				}
			} else if ( e.ColumnIndex == colLogicalOutput.Index ) {
				// logical output contract
				LogicalWebMethod lwm = wmeth.GetLogicalMethod();
				if ( lwm != null && lwm.OutputBusinessObject != null ) {
					e.Value = lwm.OutputBusinessObject.Name;
				}
			} else if ( e.ColumnIndex == colInputMapping.Index ) {
				// input mapping
				if ( wmeth.InputSchema != null ) {
					e.Value = "Input";
				} else {
					e.Value = "";
				}
			} else if ( e.ColumnIndex == colOutputMapping.Index ) {
				// output mapping
				if ( wmeth.OutputSchema != null ) {
					e.Value = "Output";
				} else {
					e.Value = "";
				}
			}
		}
		private void dgvWebMethods_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)
		{
			WebMethod wmeth = _webMethods[e.RowIndex];

			if ( e.ColumnIndex == colLogicalWMethod.Index ) {
				string name = e.Value as string;
				if ( !string.IsNullOrEmpty(name) ) {
					DataTable dt = Global.Data.SearchRepositoryItems(
						Global.Status.CurrentDomainId, ItemType.LogicalWebMethod, name, null, true);
					if ( dt != null && dt.Rows.Count > 0 ) {
						MessageBox.Show("An item with this name exists in the current domain." + Environment.NewLine + Environment.NewLine +
										"Please enter another name.",
										this.Text, MessageBoxButtons.OK, MessageBoxIcon.Stop);
						dgvWebMethods.BeginEdit(true);
						return;
					}
					LogicalWebMethod logwm = wmeth.GetLogicalMethod();
					if ( logwm == null ) {
						logwm = addLogicalMethodToWebMethod(wmeth, name, _webService.ID);
					} else {
						logwm.BeginEdit();
						logwm.Name = name;
						logwm.WebServiceID = _webService.ID;
						logwm.EndEdit(true);
					}
				}
			}
		}

		private void contextWebMethods_Opening(object sender, CancelEventArgs e)
		{

		}

		private void dgvWebMethods_CellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
		{
			if ( e.RowIndex < 0 )
				return;

			dgvWebMethods[e.ColumnIndex, e.RowIndex].Selected = true;

			bool isLogInCol = false;
			bool isLogOutCol = false;
			bool isOtherCol = true;
			if ( e.ColumnIndex == colLogicalInput.Index ) {
				isLogInCol = true;
				isOtherCol = false;
			} else if ( e.ColumnIndex == colLogicalOutput.Index ) {
				isLogOutCol = true;
				isOtherCol = false;
			}
			miSelectLogInput.Visible = isLogInCol || isOtherCol;
			miViewLogInput.Visible = isLogInCol || isOtherCol;
			miRemoveLogInput.Visible = isLogInCol || isOtherCol;
			sepLogInput.Visible = isLogInCol || isOtherCol;

			miSelectLogOutput.Visible = isLogOutCol || isOtherCol;
			miViewLogOutput.Visible = isLogOutCol || isOtherCol;
			miRemoveLogOutput.Visible = isLogOutCol || isOtherCol;
			sepLogOutput.Visible = isLogOutCol || isOtherCol;

			e.ContextMenuStrip = contextWebMethods;
		}

		private void miSelectLogInput_Click(object sender, EventArgs e)
		{
			selectLogicalInOut(true);
		}
		private void miViewLogInput_Click(object sender, EventArgs e)
		{
			viewLogicalInOut(true);
		}
		private void miRemoveLogInput_Click(object sender, EventArgs e)
		{
			removeLogicalInOut(true);
		}
		private void miSelectLogOutput_Click(object sender, EventArgs e)
		{
			selectLogicalInOut(false);
		}
		private void miViewLogOutput_Click(object sender, EventArgs e)
		{
			viewLogicalInOut(false);
		}
		private void miRemoveLogOutput_Click(object sender, EventArgs e)
		{
			removeLogicalInOut(false);
		}
		private void miViewPhysInput_Click(object sender, EventArgs e)
		{
			viewPhysicalInOut(true);
		}
		private void miViewPhysOutput_Click(object sender, EventArgs e)
		{
			viewPhysicalInOut(false);
		}

		private void dgvWebMethods_CellContentClick(object sender, DataGridViewCellEventArgs e)
		{
			if ( e.ColumnIndex == colInputMapping.Index ) {
				doMapping(true);
			} else if ( e.ColumnIndex == colOutputMapping.Index ) {
				doMapping(false);
			}
		}
		private void dgvWebMethods_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
		{
			if ( e.ColumnIndex == colLogicalWMethod.Index || e.ColumnIndex == colIcon.Index ) {
				WebMethod wm = _webMethods[e.RowIndex] as WebMethod;
				if ( wm == null ) return;
				LogicalWebMethod lwm = wm.GetLogicalMethod();
				Helpers.ShowDetails(lwm, serviceProvider);
			} else if ( e.ColumnIndex == colLogicalInput.Index ) {
				WebMethod wm = _webMethods[e.RowIndex] as WebMethod;
				if ( wm == null ) return;
				LogicalWebMethod lwm = wm.GetLogicalMethod();
				if ( lwm == null ) return;
				Helpers.ShowDetails(lwm.InputBusinessObject, serviceProvider);
			} else if ( e.ColumnIndex == colLogicalOutput.Index ) {
				WebMethod wm = _webMethods[e.RowIndex] as WebMethod;
				if ( wm == null ) return;
				LogicalWebMethod lwm = wm.GetLogicalMethod();
				if ( lwm == null ) return;
				Helpers.ShowDetails(lwm.OutputBusinessObject, serviceProvider);
			}
		}

		private void dgvWebMethods_DragOver(object sender, DragEventArgs e)
		{
			Point pt = dgvWebMethods.PointToClient(new Point(e.X, e.Y));
			DataGridView.HitTestInfo hti = dgvWebMethods.HitTest(pt.X, pt.Y);
			if ( e.Data.GetDataPresent(typeof(BusinessObject)) &&
				 hti.Type == DataGridViewHitTestType.Cell && hti.RowIndex >= 0 &&
				 ( hti.ColumnIndex == colLogicalInput.Index || hti.ColumnIndex == colLogicalOutput.Index ) ) {
				e.Effect = DragDropEffects.Link;
			} else {
				e.Effect = DragDropEffects.None;
			}
		}
		private void dgvWebMethods_DragDrop(object sender, DragEventArgs e)
		{
			if ( !e.Data.GetDataPresent(typeof(BusinessObject)) ) return;

			BusinessObject bo = (BusinessObject)e.Data.GetData(typeof(BusinessObject));
			Point pt = dgvWebMethods.PointToClient(new Point(e.X, e.Y));
			DataGridView.HitTestInfo hti = dgvWebMethods.HitTest(pt.X, pt.Y);
			if ( hti.Type == DataGridViewHitTestType.Cell && hti.RowIndex >= 0 &&
				 ( hti.ColumnIndex == colLogicalInput.Index || hti.ColumnIndex == colLogicalOutput.Index ) ) {
				WebMethod wmeth = _webMethods[hti.RowIndex];
				LogicalWebMethod lwm = wmeth.GetLogicalMethod();
				if ( lwm == null ) {
					LogicalWebMethod logwm = addLogicalMethodToWebMethod(wmeth, wmeth.Name, _webService.ID);
					logwm.BeginEdit();
					logwm.Name = wmeth.Name;
					logwm.EndEdit(true);
					dgvWebMethods.UpdateCellValue(colLogicalWMethod.Index, hti.RowIndex);
				}
				if ( hti.ColumnIndex == colLogicalInput.Index ) {
					lwm.InputBusinessObjectID = bo.ID;
					lwm.Save();
					dgvWebMethods.UpdateCellValue(colLogicalInput.Index, hti.RowIndex);
				} else if ( hti.ColumnIndex == colLogicalOutput.Index ) {
					lwm.OutputBusinessObjectID = bo.ID;
					lwm.Save();
					dgvWebMethods.UpdateCellValue(colLogicalOutput.Index, hti.RowIndex);
				}
			}
		}

		private void tabControl1_Selected(object sender, TabControlEventArgs e)
		{
			if ( e.TabPage == tabUsedBy ) {
				usedByHierarchyWebService.RepositoryItem = this.RepositoryItem as RepositoryItemBaseEx;
			}
		}

		private void btnSelectProjectLocation_Click(object sender, EventArgs e)
		{
			try {
				OpenFileDialogEx dlgOpen = new OpenFileDialogEx();
				dlgOpen.DefaultExt = ".sln";
				dlgOpen.AutoUpgradeEnabled = true;
				dlgOpen.CheckFileExists = true;
				dlgOpen.CheckPathExists = true;
				dlgOpen.AllowTfsSupport = true;
				try {
					if ( Global.Status.IsTfsInstalled ) {
						dlgOpen.TfsUri = _webService.ExtendedProperties.TfsServerUri;
						dlgOpen.Workspace = Environment.MachineName; //_webService.ExtendedProperties.TfsWorkspaceName;
					}
				} catch ( Exception ex ) {
					Debug.WriteLine(ex.ToString());
				}
				dlgOpen.FileName = txtProjectLocation.Text;
				dlgOpen.Filter = "Supported Files (*.sln;*.csproj;*.vbproj;*.vcproj)|*.sln;*.csproj;*.vbproj;*.vcproj|Solution Files (*.sln)|*.sln|C# Project Files (*.csproj)|*.csproj|VB Project Files (*.vbproj)|*.vbproj|VC++ Project Files (*.vcproj)|*.vcproj";
				if ( dlgOpen.ShowDialog() == DialogResult.OK ) {
					txtProjectLocation.Text = dlgOpen.FileName;
					if ( dlgOpen.UseTfs ) {
						try {
							_webService.ExtendedProperties.TfsServerUri = dlgOpen.TfsUri;
							_webService.ExtendedProperties.TfsWorkspaceName = dlgOpen.Workspace;
						} catch ( Exception ex ) {
							Debug.WriteLine(ex.ToString());
						}
					} else {
						_webService.ExtendedProperties.TfsServerUri = null;
						_webService.ExtendedProperties.TfsWorkspaceName = null;
					}
				}
			} catch ( FileNotFoundException fnfex ) {
				Debug.WriteLine(fnfex.ToString());
				if ( fnfex.FileName.Contains("Microsoft.TeamFoundation") ) {
					MessageBox.Show(
						"Team Foundation Server Client (Team Explorer) not available." +
						Environment.NewLine +
						"Please contact your administrator if source control is required.",
						"Select Project Location",
						MessageBoxButtons.OK,
						MessageBoxIcon.Information);
				}
			} catch ( Exception ex ) {
				Debug.WriteLine(ex.ToString());
			}
		}

		private void btnOpen_Click(object sender, EventArgs e)
		{
			bool openFolder = Form.ModifierKeys == Keys.Alt;
			try {
				string file = txtProjectLocation.Text;
				if ( File.Exists(file) ) {
					if ( openFolder ) {
						Process.Start(Path.GetDirectoryName(file));
					} else {
						Process.Start(file);
					}
				} else if ( !string.IsNullOrEmpty(_webService.ExtendedProperties.TfsWorkspaceName) ) {
					string localFile =
						TeamFoundationWrapper.GetLocalItemForServerItem(_webService, file);
					if ( File.Exists(localFile) ) {
						if ( openFolder ) {
							Process.Start(Path.GetDirectoryName(localFile));
						} else {
							Process.Start(localFile);
						}
					} else {
						MessageBox.Show("File not found. Make sure that the path is correct and the server item is mapped to a local path.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
					}
				} else {
					MessageBox.Show("File not found. Please specify a correct path", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			} catch {
				MessageBox.Show("Could not open project!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}
		#endregion


		#endregion

	}
}
